/* ------------------------------------------------------------------------*
 *
 * ------------------------------------------------------------------------*/
#include "gd25q_cmd.h"
#include "gd25q_spi.h"
#include "gd25q_manage.h"
#include "os_obj.h"
#include "common.h"
#include "sys_init.h"


#include "TouchPanel.h"

rt_ubase_t mb_rcv;

OBJ_NOCACHE uint32_t dm_buff[9*1024*1024/4+32];

data_map_info_t dm_info;

void dm_mutex_take(void);
void dm_mutex_realase(void);
void phy_write(uint32_t addr, uint8_t* dafa, uint32_t len);
void phy_read(uint32_t addr, uint8_t* dafa, uint32_t len);
void phy_erase(uint32_t addr);

data_map_t dm_cfg =
{
    /*.total_size =*/ 9 * 1024 * 1024,
    /*.block_size =*/ 32 * 1024,
    /*.phy_addr_base =*/ 0,
    /*.phy_erase_size =*/ 4 * 1024,
    /*.map =*/ (uu8*)dm_buff,
    /*.phy_write =*/ phy_write,
    /*.phy_read =*/ phy_read,
    /*.phy_erase =*/ phy_erase,
	dm_mutex_take,
	dm_mutex_realase,
    /*.info =*/ &dm_info,
};


/*----------------------------------------------------------------------------
 *                             q25 task
 *---------------------------------------------------------------------------*/
void q25_task(void   *argument)
{
    uint32_t cnt;
    uint32_t view_site = 0;
    rt_err_t rt_st;
    
	//Init_TouchPanel();
	
    gd25_spi_init();
    gd25_init(0);
    
    gd25_id_read((uint8_t*)dm_buff);
	
    GD25_DBG_INFO("gd25 id : 0x%08x \n", dm_buff[0]);
    //gd25_sector_erase(0x800000-8);
	osDelay(10000000);
	
	for(cnt = 0;cnt<16;cnt++)
	{
		dm_buff[cnt*4+0] = cnt;
	}
	
	//gd25_write(0x00700000,64,(void *) dm_buff);
	
	for(view_site=0;view_site<16;view_site++)
	{
		memset(dm_buff,5555,128);
		
		gd25_read(0x100000 * view_site,128,(uint8_t*)dm_buff);
		GD25_DBG_INFO("gd25 addr : 0x%08x\n", 0x100000 * view_site);
		
		for(cnt=0; cnt <  4;cnt++)
		{
			GD25_DBG_INFO("gd25 read : 0x%08x, 0x%08x, 0x%08x, 0x%08x \n", 
			dm_buff[cnt*4+0],
			dm_buff[cnt*4+1],
			dm_buff[cnt*4+2],
			dm_buff[cnt*4+3]);
		}
	}

    set_u8(&dm_info, 0, sizeof(dm_info));
	
	
	
    data_map_init(&dm_cfg);
	
    GD25_DBG_INFO("gd25 blocks %d\n", dm_info.block_total);
    
    for(;;)
    {
        mb_rcv = 0;
        
        if(!dm_info.load_complete)
        {
            rt_st = rt_mb_recv(os_obj.qbid_flash, &mb_rcv, ms_ticks(50));
			
			data_map_load_poll(&dm_cfg);
			
			if(dm_info.load_complete)
			{
				GD25_DBG_INFO("gd25 load complete\n");
				
				data_map_u16_read(&dm_cfg, 0x00600000, (uint16_t *)dm_buff, 64);
				
				GD25_DBG_INFO("gd25 read end: 0x%08x, 0x%08x \n", dm_buff[4],dm_buff[8]);
			}
        }
    }
}


/*-----------------------------------------------------------------------------------------------------*
* data map write
*-----------------------------------------------------------------------------------------------------*/
void phy_write(uint32_t addr, uint8_t* dafa, uint32_t len)
{
    gd25_write(addr, len, dafa);
}

/*-----------------------------------------------------------------------------------------------------*
* data map write
*-----------------------------------------------------------------------------------------------------*/
void phy_erase(uint32_t addr)
{
    gd25_sector_erase(addr);
}

/*-----------------------------------------------------------------------------------------------------*
* data map read
*-----------------------------------------------------------------------------------------------------*/
void phy_read(uint32_t addr, uint8_t* dafa, uint32_t len)
{
    gd25_read(addr, len, dafa);
	
    if(dm_info.block_load_now % 16 == 0)
	{
		GD25_DBG_INFO("gd25 load now block: %03d  - ADDR: 0x%08x - Len: %d\n", dm_info.block_load_now, addr, len);
		
		GD25_DBG_INFO("DAT: 0x%08x - 0x%08x - 0x%08x - 0x%08x\n", 
		((uint32_t *)dafa)[0],
		((uint32_t *)dafa)[4],
		((uint32_t *)dafa)[8],
		((uint32_t *)dafa)[12]
		);
	}	
}


void q25_read_mutex(uint32_t addr, uint8_t* dafa, uint32_t len)
{
	rt_mutex_take(os_obj.mid_spiflash, INT16_MAX);
	
    gd25_read(addr, len, dafa);
	
	rt_mutex_release(os_obj.mid_spiflash);
}

void q25_write_mutex(uint32_t addr, uint8_t* dafa, uint32_t len)
{
	rt_mutex_take(os_obj.mid_spiflash, INT16_MAX);
	
    gd25_write(addr, len, dafa);
	
	rt_mutex_release(os_obj.mid_spiflash);
}

void q25_eraser_mutex(uint32_t addr)
{
	rt_mutex_take(os_obj.mid_spiflash, INT16_MAX);
	
    gd25_sector_erase(addr);
	
	rt_mutex_release(os_obj.mid_spiflash);
}

void dm_mutex_take(void)
{
	rt_mutex_take(os_obj.mid_spiflash, INT16_MAX);
}

void dm_mutex_realase(void)
{
	rt_mutex_release(os_obj.mid_spiflash);
}
